<?php
define(LOG_FILE,"Z:\\home\\project.tk\\log.txt");
define(LOG_MAIL,"mnatsakanyan.ashot@yandex.ru");

class Error {
	
	private $code;
	private $userMessage;
	private $logMessage;
	private $log;
	private $errorType = "ERROR : ";
	
	public function __construct() {
		set_error_handler(array($this, 'errorHandler'));
		set_exception_handler(array($this, 'exceptionHandler'));
	}
	public function getUserMessage() {
		return $this->userMessage;
	}
	public function setError( $code, $logMessage=null, $logStack=true ) {
		$code = $this->codeToString($code);
		$this->code = $code;
		$test = @constant("ERROR_".$code);
		if( isset($test) ) {
			$this->userMessage = $test;
		} else {
			$this->userMessage = "ERROR_".$code;
		}
		if( isset($logMessage) ) {
			$this->logMessage = $logMessage;
		}
		if( $logStack ) {
			$this->errorType = "ERROR : ";
			$this->log = $this->getStackTrace();
		}
		$date = date("H:i:s Y-m-d");
		$log = "{$this->errorType} [{$date}] {$this->logMessage} [ User Message : \"{$this->userMessage}\" ] {$this->log}\n";
		error_log($log);
		error_log($log,1,LOG_MAIL,"{$this->errorType} {$this->log}");
		error_log($log,3,LOG_FILE);
	}
	public function errorHandler($errno, $errstr, $errfile, $errline) {
		if (!(error_reporting() & $errno)) {
			return;
		}
		$this->log =  $errfile.":".$errline;
		$this->errorType = $this->friendlyErrorType($errno);
		$this->setError( $errno, $errstr, false);
		return true;
	}
	public function exceptionHandler($exception) {
		$this->errorType = "EXCEPTION : ";
		$this->log = $exception->getFile().":".$exception->getLine();
		$this->setError( $exception->getCode(), $exception->getMessage(), false);
	}
	private function friendlyErrorType($type) {
		$return = "";
		if ($type & E_ERROR) // 1 //
			$return .= '& E_ERROR ';
		if ($type & E_WARNING) // 2 //
			$return .= '& E_WARNING ';
		if ($type & E_PARSE) // 4 //
			$return .= '& E_PARSE ';
		if ($type & E_NOTICE) // 8 //
			$return .= '& E_NOTICE ';
		if ($type & E_CORE_ERROR) // 16 //
			$return .= '& E_CORE_ERROR ';
		if ($type & E_CORE_WARNING) // 32 //
			$return .= '& E_CORE_WARNING ';
		if ($type & E_COMPILE_ERROR) // 64 //
			$return .= '& E_COMPILE_ERROR ';
		if ($type & E_COMPILE_WARNING) // 128 //
			$return .= '& E_COMPILE_WARNING ';
		if ($type & E_USER_ERROR) // 256 //
			$return .= '& E_USER_ERROR ';
		if ($type & E_USER_WARNING) // 512 //
			$return .= '& E_USER_WARNING ';
		if ($type & E_USER_NOTICE) // 1024 //
			$return .= '& E_USER_NOTICE ';
		if ($type & E_STRICT) // 2048 //
			$return .= '& E_STRICT ';
		if ($type & E_RECOVERABLE_ERROR) // 4096 //
			$return .= '& E_RECOVERABLE_ERROR ';
		if ($type & E_DEPRECATED) // 8192 //
			$return .= '& E_DEPRECATED ';
		if ($type & E_USER_DEPRECATED) // 16384 //
			$return .= '& E_USER_DEPRECATED ';
		return substr ( $return, 2 );
	}
	private function getStackTrace($skip = 1){
		$aTrace = debug_backtrace();
		$ret = '';
		foreach($aTrace as $traceLine) {
			if($skip<=0) {
				if(!empty($traceLine['file'])){
					$ret .= $traceLine['file'].':';
				}
				if(!empty($traceLine['line'])){
					$ret .= $traceLine['line'].' ';
				}
				if(!empty($traceLine['class'])){
					$ret .= $traceLine['class'];
				}
				if(!empty($traceLine['type'])){
					$ret .= $traceLine['type'];
				}
				if(!empty($traceLine['function'])){
					$ret .= $traceLine['function'];
				}
				$ret .= "\n";
			} else {
				$skip--;
			}
		}
		return $ret;
	}
	private function codeToString($code){
		$do = strlen($code);
		$ret ="";
		for($i=0;$i<4-$do;$i++) {
			$ret .= "0";
		}
		$ret .= $code;
		return $ret; 
	}
}

?>